package warbots.gameplay;

import java.awt.Point;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

import warbots.entities.actions.Action;
import warbots.entities.units.Unit;
import warbots.entities.units.UnitFactory;
import warbots.gameplay.exceptions.GameplayException;
import warbots.gameplay.exceptions.NotEnoughMoneyException;

/**
 * @author Ido Adler.
 */
public class Player
{
    private Set<Unit> units;
    private String _name;
    private int money;
    
    /**
     * TODO: description
     * 
     * @param string
     */
    public Player(final String name)
    {
        setName(name);
        units = new HashSet<Unit>();
        
    }
    
    /**
     * TODO: description
     * 
     * @throws GameplayException
     */
    public Unit chooseUnit() throws GameplayException
    {
        String unit = GamePlay.read(getName() + " which unit do you want? ");
        String[] actions =
            GamePlay.read(getName() + " which actions to add (comma seperated)? ").split(",");
        Unit created = UnitFactory.newInstance(this, unit, actions);
        addUnit(created);
        return created;
    }
    
    public void setName(final String _name)
    {
        this._name = _name;
    }
    
    public String getName()
    {
        return _name;
    }
    
    public boolean removeUnit(final Unit unit)
    {
        return getUnits().remove(unit);
    }
    
    public boolean addUnit(final Unit unit)
    {
        return getUnits().add(unit);
    }
    
    public Set<Unit> getUnits()
    {
        return units;
    }
    
    private void setMoney(final int money)
    {
        this.money = money;
    }
    
    public void deposit(final int sum) throws GameplayException
    {
        if (sum < 0)
            throw new GameplayException("you're cheating");
        
        setMoney(getMoney() + sum);
        
    }
    
    public void withdraw(final int sum) throws GameplayException
    {
        if (sum < 0)
            throw new GameplayException("you're cheating");
        if (sum > getMoney())
            throw new NotEnoughMoneyException("poor bastard");
        
        setMoney(getMoney() - sum);
    }
    
    public int getMoney()
    {
        return money;
    }
    
    public boolean isAlive(){
    	return !getUnits().isEmpty();
    }
    
    /**
     * This is the function read by the main game loop on every turn of this player
     * @param map
     */
    public void turn(Map map){
    	Unit unit = map.chooseUnit(getUnits());
    	// if the map did not choose a unit to play, the player can set his desired unit.
    	if (unit == null){
    		// implement some strategy here probably
    		unit = getUnits().iterator().next();
    	}
    	
    	// implement some strategy here probably
    	// choose unit action
    	Action action = unit.chooseAction(GamePlay.read(_name+" choose action "+Arrays.toString(unit.getActionNames())+": "));
    	Point target = map.chooseCell();
    	boolean success = action.execute(map, target);
    	while (!success)
    	{
    		System.out.println("action can't be preformed, please try again");
    		action = unit.chooseAction(GamePlay.read(" choose action "+Arrays.toString(unit.getActionNames())+": "));
        	target = map.chooseCell();
        	success = action.execute(map, target);
    	}
    }
}
